package com.study.zgw.nio;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;

public class Server {

    public static void main(String[] args) {
        try {
            Selector selector = Selector.open();
            ServerSocketChannel server = ServerSocketChannel.open();
            server.bind(new InetSocketAddress(8080));
            server.configureBlocking(false); //非阻塞
            SelectionKey selectKey = server.register(selector, 0, null);
            selectKey.interestOps(SelectionKey.OP_ACCEPT); //selectKey只关注accept事件
            System.out.println("----selectKey "+selectKey);

            while (true){
                selector.select();//阻塞等待连接事件
                Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
                while (iter.hasNext()){
                    SelectionKey key = iter.next();
                    if (key.isAcceptable()) {
                        System.out.println("------->accept事件: "+key);
                        ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                        SocketChannel sc = channel.accept();
                        sc.configureBlocking(false);
                        SelectionKey keyRead = sc.register(selector, 0, null);
                        keyRead.interestOps(SelectionKey.OP_READ);
                        System.out.println("-----channel "+sc);
                        System.out.println("-----read key "+keyRead);
                        sc.write(Charset.defaultCharset().encode("服务器连接成功:"));
                    }else if (key.isReadable()){
                        try {
                            System.out.println("------->read事件: "+key);
                            SocketChannel readChannel = (SocketChannel) key.channel();
                            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                            int read = readChannel.read(byteBuffer);
                            if (-1 == read){  //正常断开客户端连接
                                key.cancel();
                            }else {
                                byteBuffer.flip();//切换读模式
                                byte[] byteResult = new byte[byteBuffer.limit()];
                                for (int i=0;i<byteBuffer.limit();i++){
                                    byteResult[i] = byteBuffer.get();
                                }
                                String data = new String(byteResult, StandardCharsets.UTF_8);
                                System.out.println("------收到的数据："+data);
                                System.out.println("------channel: "+readChannel);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                            key.cancel(); //异常删除key 避免重新遍历
                        }
                    }
                    iter.remove();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
